package com.sjgtw.cloud.file.controller;

import com.sjgtw.cloud.common.core.domain.R;
import com.sjgtw.cloud.common.core.utils.DateUtils;
import com.sjgtw.cloud.common.core.utils.StringUtils;
import com.sjgtw.cloud.common.core.utils.file.FileUtils;
import com.sjgtw.cloud.file.config.MinioConfig;
import com.sjgtw.cloud.file.domain.SupUploadFile;
import com.sjgtw.cloud.file.domain.SysFiles;
import com.sjgtw.cloud.file.service.ISysFileService;
import com.sjgtw.cloud.system.api.domain.SysFile;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

/**
 * <p>Title: 文件管理服务-Controller</p>
 * <p>Description: </p>
 * @author Admin
 * @date 2021-4-12
 */
@RestController
@Api(tags = "文件管理")
public class SysFileController
{
	private static final Logger log = LoggerFactory.getLogger(SysFileController.class);

	@Autowired
	private ISysFileService sysFileService;

	@Autowired
	private MinioConfig minioConfig;

	/**
	 * <p>Title: 上传文件</p>
	 * <p>Description: </p>
	 * @param file
	 * @return
	 */
	@PostMapping("/upload")
	@ApiOperation("上传文件")
	public R<SysFile> upload(MultipartFile file) {
		try {
			// 上传并返回访问地址
			String url = sysFileService.uploadFile(file);
			String realFilename = file.getOriginalFilename();
			SysFile sysFile = new SysFile();
			sysFile.setName(realFilename);
			sysFile.setUrl(url);
			return R.ok(sysFile);
		} catch (Exception e) {
			log.error("上传文件失败", e);
			return R.fail(e.getMessage());
		}
	}

	@ApiOperation("文件下载")
	@GetMapping("/download")
	public void downloads(String path,String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
		path = path.replace(minioConfig.getUrl().concat("/").concat(minioConfig.getBucketName().concat("/")),"");
		path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
		InputStream inputStream = sysFileService.download(path);
		try {
			byte buf[] = new byte[1024];
			int length = 0;
			response.reset();
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
			response.setContentType("application/octet-stream");
			response.setCharacterEncoding(StandardCharsets.UTF_8.name());
			OutputStream outputStream = response.getOutputStream();
			while ((length = inputStream.read(buf)) > 0) {
				outputStream.write(buf, 0, length);
			}
			outputStream.flush();
			outputStream.close();
		} catch (Exception ex) {
			System.out.println("导出失败："+ ex.getMessage());
		}
	}

	@ApiOperation("/文件打包下载")
	@PostMapping("/downloads")
	public void download(@RequestBody SysFiles sysFiles, HttpServletResponse response) throws Exception {
		String date = DateUtils.getDate();
		//打包名称
		String zipFileName = date.concat("-").concat(UUID.randomUUID().toString().replace("-",""));

		response.reset();
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipFileName.concat(".zip"), StandardCharsets.UTF_8.name()));
		response.setContentType("application/octet-stream");
		response.setCharacterEncoding(StandardCharsets.UTF_8.name());
		ServletOutputStream outputStream = response.getOutputStream();

		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);

		ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);
		zipOutputStream.setEncoding(StandardCharsets.UTF_8.name());

		List<SupUploadFile> files = sysFiles.getList();
		for (SupUploadFile file : files) {
			String path = file.getFilePath();
			path = path.replace(minioConfig.getUrl().concat("/").concat(minioConfig.getBucketName().concat("/")),"");
			path = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
			InputStream download = sysFileService.download(path);
			if (StringUtils.isNull(download)) {
				continue;
			}
			setOutputStream(zipOutputStream,file.getFileName(),download);
		}
		zipOutputStream.closeEntry();
		zipOutputStream.close();
		bufferedOutputStream.flush();
		bufferedOutputStream.close();
		outputStream.flush();
		outputStream.close();
	}


	private void setOutputStream(ZipOutputStream outputStream, String fileName, InputStream inputStream) throws IOException {
		outputStream.putNextEntry(new ZipEntry(fileName));
		BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
		byte[] bytes = new byte[1024];
		int len = -1;
		while ((len = bufferedInputStream.read(bytes)) != -1) {
			outputStream.write(bytes,0,len);
		}
		bufferedInputStream.close();
	}

}